iT邦幫忙

2024 iThome 鐵人賽

DAY 22
0
Security

picoCTF 刷題分享系列 第 22

picoCTF 刷題分享---Day 22(刷題去)

  • 分享至 

  • xImage
  •  

昨天的那篇很麻煩吧!!所以從聰明如我只會用第一種方法喔(畢竟我們要善用電腦對吧/images/emoticon/emoticon12.gif


題目:ARMssembly 1
題目的意思我想了好久,他的意思是要找到一個數(k)使得./chall_1 k 2 3要顯示you win!
他的description有夠不清楚,害我卡好久

	.arch armv8-a
	.file	"chall_1.c"
	.text
	.align	2
	.global	func
	.type	func, %function
func:
	sub	sp, sp, #32 // sp 往下分配32個Byte給堆疊
	str	w0, [sp, 12] // 將w0的值 (58)存入地址[sp, 12]
	mov	w0, 58 // 將w0的值設為58(這裡是將58設為一個固定值,所以你的arg1是多少,並不會影響這裡的58)
	str	w0, [sp, 16] // 將w0的值 (58)存入地址[sp, 16]
	mov	w0, 2 // 將w0的值設為2
	str	w0, [sp, 20] // 將w0的值 (2)存入地址[sp, 20]
	mov	w0, 3 // 將w0的值設為3
	str	w0, [sp, 24] // 將w0的值 (3)存入地址[sp, 20]
	ldr	w0, [sp, 20] // 將[sp, 20]的值 (2)載入w0
	ldr	w1, [sp, 16] // 將[sp, 16]的值 (58)載入w1
	lsl	w0, w1, w0 // 對w1進行左移w0個(w0 = w1 << w0)
	str	w0, [sp, 28] // 將w0的值 (232)存入地址[sp, 28]
	ldr	w1, [sp, 28] // 將[sp, 28]的值 (232)載入w1
	ldr	w0, [sp, 24] // 將[sp, 24]的值 (3)載入w1
	sdiv	w0, w1, w0 // 進行整數除法w0 = w1//w0(232//3 = 77)
	str	w0, [sp, 28] // 將w0的值 (77)存入地址[sp, 28]
	ldr	w1, [sp, 28] // 將[sp, 28]的值 (77)載入w1
	ldr	w0, [sp, 12] // 將[sp, 12]的值 (58)載入w0
	sub	w0, w1, w0 // w0 = w1 - w0 (w0 = 77-58 = 19)
	str	w0, [sp, 28] // 將w0的值 (19)存入地址[sp, 28]
	ldr	w0, [sp, 28] // 將[sp, 28]的值 (19)載入w1
	add	sp, sp, 32 // 釋放為該函數分配的堆疊空間
	ret // 返回呼叫點
	.size	func, .-func
	.section	.rodata
	.align	3
.LC0:
	.string	"You win!"
	.align	3
.LC1:
	.string	"You Lose :("
	.text
	.align	2
	.global	main
	.type	main, %function
main:
	stp	x29, x30, [sp, -48]! // 保存鏈接寄存器 (x30) 和幀指標 (x29),
							 //並分配 48 Byte堆疊空間
	add	x29, sp, 0 // 設置新的幀指標
	str	w0, [x29, 28] // 把w0的值給 x29+28 的地址 (這是輸入的參數 (58))
	str	x1, [x29, 16] // 把x1的值給 x29+16 的地址 (這是輸入的參數 (2))
	ldr	x0, [x29, 16] // 加載指向命令列參數的指針(即 argv)
	add	x0, x0, 8 // 跳過第一個參數,因為 argv[0] 是程式名稱
	// 在 64 位元的 ARMv8 架構中,指針的大小是 8 Byte,因此 argv 中每個元素
	// (每個字串的指針)都佔用 8 Byte。
	ldr	x0, [x0] // 加載 argv[1]
	bl	atoi // 將 argv[1] 轉換為整數,
	// 可以查看https://developer.arm.com/documentation/101655/0961/Cx51-User-s-Guide/Library-Reference/Reference/atoi
	str	w0, [x29, 44] // 將轉換後的整數結果存入 x29 + 44
	ldr	w0, [x29, 44] // 加載轉換後的整數
	// 要做這種看似無意義的事,其實是為了保證w0的資料不要被任何意外給洗掉
	bl	func // 呼叫func函式(這時w0 = 58)
	cmp	w0, 0 // w0 = 19 19-0>0 (CF=0 ,ZF=0)
	bne	.L4 // 當結果不等於0(也就是ZF=0)時跳到.L4
	//當不符合bne則執行以下
	adrp	x0, .LC0 //準備一個字符串(.LC0)
	add	x0, x0, :lo12:.LC0 // x0 = x0 + .LC0(以顯示 "You Win! :(" 的信息。)
	bl	puts
	b	.L6
.L4:
	adrp	x0, .LC1 //adrp可以上網查一下,簡單來說獲取 .LC1 的頁面基址,存入 x0
	add	x0, x0, :lo12:.LC1 // x0 = x0 + .LC1 的低12位,獲取完整地址
	bl	puts
	// 白話文:這些指令的作用是準備一個字符串(.LC1)並將其傳遞給 puts 函數,
	// 以顯示 "You Lose :(" 的信息。
	// 由此可知只要不符合bne	.L4 即可跳過這裡
.L6:
	nop
	ldp	x29, x30, [sp], 48
	ret
	.size	main, .-main
	.ident	"GCC: (Ubuntu/Linaro 7.5.0-3ubuntu1~18.04) 7.5.0"
	.section	.note.GNU-stack,"",@progbits
  • 可以看到我們要做的事就是讓w0最後等於0跳過.L4
  • 所以重點在於
    • lsl w0, w1, w0 // w0 = 232
    • sdiv w0, w1, w0 // w0 = 77
    • sub w0, w1, w0 // w0 = 77-k要等於0
    • 58*4/3 - k=0 => 77-k=0
    • 所以k = 77
    • 77的hexadecimal = 0x4d
    • 所以依照他的格式:0000004d(8位)
    • 格式:picoCTF{0000004d}

後記:
哭慘,結果都要不只要執行,還要了解程式碼,我的命都沒了🫠🫠這題好可怕,解開後還要計算,對我是蠻不輕鬆的,這題搞了好久最後的reverse還有點迷糊,我還在試著完全理解中,完全是通靈啊,我的媽/images/emoticon/emoticon02.gif


上一篇
picoCTF 刷題分享---Day 21(刷題去)
下一篇
picoCTF 刷題分享---Day 23(刷題去)
系列文
picoCTF 刷題分享30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
abac940103
iT邦新手 5 級 ‧ 2024-10-06 22:57:56

抱歉排版超亂,我沒注意到!!😭😭😭

我要留言

立即登入留言